#!/bin/bash

XFSTESTS_FLAVOR=kvm
t=$(echo ${XFSTESTS_FLAVOR}_xfstests_dir | tr "[:lower:]" "[:upper:]")
eval DIR="\$$t"
if test -z "$DIR"
then
    DIR="$(dirname "$(readlink -f "$0")")"
fi
if test ! -f "$DIR/util/get-config"
then
    echo "$(basename "$0"): couldn't find $DIR/util/get-config"
    exit 1
fi

. "$DIR/util/get-config"
. "$DIR/util/parse_opt_funcs"
. "$DIR/util/arch-funcs"

case "$1" in
    install-kconfig)
	shift
	if test ! -x "$KBUILD_DIR/install-kconfig"
	then
	    echo "Kernel configuration not supported in this installation"
	    exit 1
	fi
	"$KBUILD_DIR/install-kconfig" "$@"
	exit $?
	;;
    kbuild)
	shift
	if test ! -x "$KBUILD_DIR/kbuild"
	then
	    echo "kbuild not supported in this installation"
	    exit 1
	fi
	"$KBUILD_DIR/kbuild" "$@"
	exit $?
	;;
    setup)
	shift
	export KVM_XFSTESTS_DIR="$DIR"
	XFSTESTS_FLAVOR=$XFSTESTS_FLAVOR "$DIR/util/kvm-do-setup" "$@"
	exit $?
	;;
esac

QUIET="quiet loglevel=0"

. $DIR/util/parse_cli

if test -z "$EXPLICIT_ROOT_FS" ; then
    ROOT_FS="$(dirname $DIR)/test-appliance/root_fs.img.$ARCH"
    if ! test -f "$ROOT_FS" ; then
	ROOT_FS="$(dirname $DIR)/test-appliance/root_fs.img"
    fi
fi

if ! test -f "$ROOT_FS" ; then
    echo "Can't find root_fs image: $ROOT_FS"
    exit 1
fi

if ! test -f "$KERNEL"; then
     echo "$KERNEL: kernel not found"
     exit 1
fi

if test -n "$NO_ACTION" ; then
    echo "Using kernel $KERNEL"
fi

if test -z "$DO_NET" ; then
    echo "Networking disabled."
    NET="-net none "
else
    ARG="$ARG net.ifnames=0"
    if test $(whoami) = "root" ; then
	NET="-net nic,model=virtio -net tap,script=$IFUP,downscript=$IFDOWN "
    else
	NET="-netdev user,id=mynet0,net=172.20.0.0/24 -device virtio-net,netdev=mynet0 "
    fi
fi

EXTRA_ARG=$(echo "$EXTRA_ARG" | sed -e 's/:/ /')

if test -z "$TESTRUNID" ; then
    TESTRUNID=$(date +%Y%m%d%H%M)
fi
if test -n "$SKIP_LOG" ; then
    LOGFILE=/tmp/log.$TESTRUNID
else
    mkdir -p "$DIR/logs"
    LOGFILE="$DIR/logs/log.$TESTRUNID"
    RESULTFILE="$DIR/logs/results-$TESTRUNID.tar.xz"
fi

if test -n "$INITRD" ; then
    INITRD="--initrd $INITRD"
fi

if ! test -e $VDB -a -e $VDC -a -e $VDD -a -e $VDE -a -e $VDF -a -e $VDG \
     -a -e $VDI -a -e $VDJ
then
	echo "Test disks don't exist, running setup..."
	$DIR/util/kvm-do-setup
fi

for i in "$VDB" "$VDC" "$VDD" "$VDE" "$VDF" "$VDG" "$VDI" "$VDJ"
do
    if ! test -e "$i"
    then
	echo "Fatal error: disk $i does not exit.  Config error?"
	exit 1;
    fi
done

if ionice -h > /dev/null ; then
    IONICE="ionice -n 5"
fi

if test -z "$VIRTFS_PATH"; then
    VIRTFS_PATH=/tmp/kvm-xfstests-$USER
fi
VIRTFS="-fsdev local,id=v_tmp,path=$VIRTFS_PATH,security_model=none "
VIRTFS+="-device virtio-9p-pci,fsdev=v_tmp,mount_tag=v_tmp "

if test -z "$VIRTFS_MODEL"; then
    VIRTFS_MODEL=none
fi
if test -n "$VIRTFS_TEST_PATH"; then
    VIRTFS+="-fsdev local,id=p9test,path=$VIRTFS_TEST_PATH,"
    VIRTFS+="security_model=$VIRTFS_MODEL "
    VIRTFS+="-device virtio-9p-pci,fsdev=p9test,mount_tag=9ptest "
fi
if test -n "$VIRTFS_SCRATCH_PATH"; then
    VIRTFS+=" -fsdev local,id=p9scratch,path=$VIRTFS_SCRATCH_PATH,"
    VIRTFS+="security_model=$VIRTFS_MODEL "
    VIRTFS+="-device virtio-9p-pci,fsdev=p9scratch,mount_tag=9pscratch "
fi

VDH="$ourtmp/kvm-vdh"
tar -c -f "$VDH" -T /dev/null

if test -z "$NO_ACTION" -a "$UPDATE_XFSTESTS" = "yes"
then
    tar -r -f $VDH -C "$DIR/../fstests-bld" xfstests.tar.gz
fi

if test -z "$NO_ACTION" -a "$UPDATE_EXTRA_TESTS" = "yes"
then
    tar -r -f $VDH -C "$ourtmp" extra-tests.tar.gz
fi

if test -z "$NO_ACTION" -a "$UPDATE_FILES" = "yes"
then
    TDIR=$(mktemp -d /tmp/files.XXXXXXXX)
    if test -z "$TDIR"; then
	echo "Couldn't create temp directory"
	exit 1
    fi
    (cd "$DIR/../test-appliance"; \
     tar -X kvm-exclude-files -C files \
		--owner=root --group=root --mode=go+u-w -cf - . | \
	 gzip -9n > "$TDIR/files.tar.gz")
    tar -r -f $VDH -C "$TDIR" files.tar.gz
    rm -rf "$TDIR"
fi

if test -n "$MODULES" -a -f "$MODULES"
then
    if test -z "$NO_ACTION" ; then
	tar -r -f $VDH -C $(dirname "$MODULES") \
	    --transform="s/.*/modules.tar.xz/" $(basename "$MODULES")
    else
	echo "Using modules from $MODULES"
    fi
fi

fallocate -l 128M "$VDH"
chmod 600 "$VDH"

mkdir -p /tmp/kvm-xfstests-$USER

case "$ARCH" in
    i386|amd64)
	QEMU_ARCH=x86_64
	ACCEL=kvm:tcg
	CONSOLE_DEV=ttyS0
	MACHINE_TYPE=q35
	CPU_TYPE=max
	;;
    arm64)
	QEMU_ARCH=aarch64
	ACCEL=tcg
	CONSOLE_DEV=ttyAMA0
	MACHINE_TYPE=virt
	CPU_TYPE=max
	;;
    *)
	echo "Unsupported architecture: $ARCH"
	exit 1;
esac
QEMU="qemu-system-$QEMU_ARCH"

$NO_ACTION $IONICE $QEMU -boot order=c $NET \
	-machine $MACHINE_TYPE,accel=$ACCEL -cpu $CPU_TYPE \
	-drive file=$ROOT_FS,if=virtio$SNAPSHOT \
	-drive file=$VDB,cache=$CACHE,if=virtio,format=raw$AIO \
	-drive file=$VDC,cache=$CACHE,if=virtio,format=raw$AIO \
	-drive file=$VDD,cache=$CACHE,if=virtio,format=raw$AIO \
	-drive file=$VDE,cache=$CACHE,if=virtio,format=raw$AIO \
	-drive file=$VDF,cache=$CACHE,if=virtio,format=raw$AIO \
	-drive file=$VDG,cache=none,if=virtio,format=raw$AIO \
	-drive file=$VDH,if=virtio,format=raw \
	-drive file=$VDI,cache=$CACHE,if=virtio,format=raw$AIO \
	-drive file=$VDJ,cache=$CACHE,if=virtio,format=raw$AIO \
	-vga none -nographic -smp $NR_CPU -m $MEM \
	$VIRTFS \
	$VIRTIO_RNG \
	$CONSOLE \
	$MONITOR \
	$SERIAL \
	$GDB \
	$NUMA \
	--kernel $KERNEL \
	$INITRD \
	--append "$QUIET root=$ROOT_DEV console=$CONSOLE_DEV,115200 nokaslr $ARG $EXTRA_ARG" |\
tee $LOGFILE

if test -n "$DO_ARCHIVE"; then
    tar -O -xf "$VDH" results.tar.xz > $RESULTFILE
    echo "result  in $RESULTFILE"
fi
if test -n "$SKIP_LOG" ; then
    rm $LOGFILE
else
    sed -i -e '/^-------------------- Summary report/,$d' $LOGFILE
    echo "logfile in $LOGFILE"
fi
# Fix line wrap from qemu
echo -ne '\e[?7h'
